#ifndef _FeedPack_H_
#define _FeedPack_H_


#define FEED_PACK_DATA_SIZE                 (FEED_FRAME_DATA_SIZE + 4)


/* 地址定义 */
typedef enum {
    FEED_ADDR_DEVICE = 0,                   /* 设备 */
    FEED_ADDR_IOT,                          /* IOT模组 */
    FEED_ADDR_SERVER,                       /* 服务器 */
    FEED_ADDR_UPPER,                        /* 上位机 串口 */
    FEED_ADDR_APP,                          /* APP */
    FEED_ADDR_BT,                           /* 蓝牙 */
    FEED_ADDR_UDP,                          /* 上位机 UDP */
    FEED_ADDR_TCP,                          /* 上位机 TCP */
} FeedPhyChannelEnum;


typedef enum {
    FEED_PACK_STATE_HEAD0 = 0,
    FEED_PACK_STATE_HEAD1,
    FEED_PACK_STATE_VERSION,
    FEED_PACK_STATE_NO,
    FEED_PACK_STATE_CHANNEL,
    FEED_PACK_STATE_TYPE,
    FEED_PACK_STATE_LENGTH_LOW,
    FEED_PACK_STATE_LENGTH_HIGH,
    FEED_PACK_STATE_DATAS,
    FEED_PACK_STATE_CRC_LOW,
    FEED_PACK_STATE_CRC_HIGH,
    FEED_PACK_STATE_END,
} FeedPackStateEnum;

typedef struct{
    uint8_t head[2];                        /* 0x55AA */
    uint8_t version;                        /* 协议版本 */
    uint8_t No;                             /* 每发送1次，自动+1 */
    uint8_t source          : 4;            /* 来源：0:设备、1:IOT模组、2:服务器、3:log串口、4:APP、5:蓝牙、6:UDP、7:TCP */
    uint8_t target          : 4;            /* 目标：0:设备、1:模组、2:服务器、3:APP */
    uint8_t get             : 1;            /* 0:更新、1:请求 */
    uint8_t response        : 1;            /* 是否为响应 */
    uint8_t rec             : 6;            /* 预留 */
    uint16_t length;                        /* 数据长度 */
    uint8_t datas[FEED_PACK_DATA_SIZE];     /* 数据 */
    uint16_t crc;                           /* 从head到crc前的CRC_MODBUS校验值 */
    uint16_t cnt;                           /* 已解析数据大小 */
    uint8_t state;                          /* 解析状态 */
}FeedPackType;


int8_t cFeedPackEncode(FeedPackType *ptypePack);
int8_t cFeedPackAnalysis(uint32_t uiChannel, void *pvDatas, int32_t iLength);

int8_t cFeedPackFrameSingleUpdate(uint8_t ucTarget, uint8_t ucSource, uint16_t usID, uint8_t ucType, int32_t iValue, float fValue, double dValue, void *pvDatas, int32_t iLength);
#define cFeedPackFrameUpdateInt(ucTarget, ucSource, usID, iValue)           cFeedPackFrameSingleUpdate((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_INT, iValue, 0.0f, 0.0, NULL, 0)
#define cFeedPackFrameUpdateFloat(ucTarget, ucSource, usID, fValue)         cFeedPackFrameSingleUpdate((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_FLOAT, 0, fValue, fValue, NULL, 0)
#define cFeedPackFrameUpdateDouble(ucTarget, ucSource, usID, dValue)        cFeedPackFrameSingleUpdate((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_FLOAT, 0, dValue, dValue, NULL, 0)
#define cFeedPackFrameUpdateString(ucTarget, ucSource, usID, pvDatas)       cFeedPackFrameSingleUpdate((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_STRING, 0, 0.0f, 0.0, (pvDatas), strlen((char *)pvDatas))
#define cFeedPackFrameUpdateRaw(ucTarget, ucSource, usID, pvDatas, iLength) cFeedPackFrameSingleUpdate((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_RAW, 0, 0.0f, 0.0, (pvDatas), (iLength))

int8_t cFeedPackFrameSingleSet(uint8_t ucTarget, uint8_t ucSource, uint16_t usID, uint8_t ucType, int32_t iValue, float fValue, double dValue, void *pvDatas, int32_t iLength);
#define cFeedPackFrameSetInt(ucTarget, ucSource, usID, iValue)              cFeedPackFrameSingleSet((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_INT, iValue, 0.0f, 0.0, NULL, 0)
#define cFeedPackFrameSetFloat(ucTarget, ucSource, usID, fValue)            cFeedPackFrameSingleSet((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_FLOAT, 0, fValue, fValue, NULL, 0)
#define cFeedPackFrameSetDouble(ucTarget, ucSource, usID, dValue)           cFeedPackFrameSingleSet((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_FLOAT, 0, dValue, dValue, NULL, 0)
#define cFeedPackFrameSetString(ucTarget, ucSource, usID, pvDatas)          cFeedPackFrameSingleSet((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_STRING, 0, 0.0f, 0.0, (pvDatas), strlen((char *)pvDatas))
#define cFeedPackFrameSetRaw(ucTarget, ucSource, usID, pvDatas, iLength)    cFeedPackFrameSingleSet((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_RAW, 0, 0.0f, 0.0, (pvDatas), (iLength))
int8_t cFeedPackFrameSingleGet(uint8_t ucTarget, uint8_t ucSource, uint16_t usID);

int8_t cFeedPackJsonSingleUpdate(uint8_t ucTarget, uint8_t ucSource, uint16_t usID, uint8_t ucType, int32_t iValue, float fValue, double dValue, void *pvDatas, int32_t iLength);
#define cFeedPackJsonUpdateInt(ucTarget, ucSource, usID, iValue)            cFeedPackJsonSingleUpdate((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_INT, iValue, 0.0f, 0.0, NULL, 0)
#define cFeedPackJsonUpdateFloat(ucTarget, ucSource, usID, fValue)          cFeedPackJsonSingleUpdate((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_FLOAT, 0, fValue, fValue, NULL, 0)
#define cFeedPackJsonUpdateDouble(ucTarget, ucSource, usID, dValue)         cFeedPackJsonSingleUpdate((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_FLOAT, 0, dValue, dValue, NULL, 0)
#define cFeedPackJsonUpdateString(ucTarget, ucSource, usID, pvDatas)        cFeedPackJsonSingleUpdate((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_STRING, 0, 0.0f, 0.0, (pvDatas), strlen((char *)pvDatas))
#define cFeedPackJsonUpdateRaw(ucTarget, ucSource, usID, pvDatas, iLength)  cFeedPackJsonSingleUpdate((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_RAW, 0, 0.0f, 0.0, (pvDatas), (iLength))

int8_t cFeedPackJsonSingleSet(uint8_t ucTarget, uint8_t ucSource, uint16_t usID, uint8_t ucType, int32_t iValue, float fValue, double dValue, void *pvDatas, int32_t iLength);
#define cFeedPackJsonSetInt(ucTarget, ucSource, usID, iValue)              cFeedPackJsonSingleSet((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_INT, iValue, 0.0f, 0.0, NULL, 0)
#define cFeedPackJsonSetFloat(ucTarget, ucSource, usID, fValue)            cFeedPackJsonSingleSet((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_FLOAT, 0, fValue, fValue, NULL, 0)
#define cFeedPackJsonSetDouble(ucTarget, ucSource, usID, dValue)           cFeedPackJsonSingleSet((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_FLOAT, 0, dValue, dValue, NULL, 0)
#define cFeedPackJsonSetString(ucTarget, ucSource, usID, pvDatas)          cFeedPackJsonSingleSet((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_STRING, 0, 0.0f, 0.0, (pvDatas), strlen((char *)pvDatas))
#define cFeedPackJsonSetRaw(ucTarget, ucSource, usID, pvDatas, iLength)    cFeedPackJsonSingleSet((ucTarget), (ucSource), (usID), FEED_FRAME_TYPE_RAW, 0, 0.0f, 0.0, (pvDatas), (iLength))
int8_t cFeedPackJsonSingleGet(uint8_t ucTarget, uint8_t ucSource, uint16_t usID);

#endif
